﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Api.Model;
using System.Net;
using TypeMock.ArrangeActAssert;
using CThru.Silverlight;

namespace RssProxyService.Test.Unit
{
    [TestFixture]
    public class RssProxyServiceTests
    {
        [Test]
        public void IsPaginationSupported_Always_ReturnFalse()
        {
            RssProxyService service = new RssProxyService(null, null, null);
            Assert.False(service.IsPaginationSupported);
        }

        [Test]
        public void GetPaginatedArticlesAsync_Always_ThrowsInvalidOperationExcpetion()
        {
            RssProxyService service = new RssProxyService(null, null, null);
            Assert.Throws<NotSupportedException>(() 
                => service.GetPaginatedArticlesAsync(0, 0, null));
        }

        [Test]
        public void GetArticlesAsync_NullCallbackPassed_ThrowsArgumentNullException()
        {
            RssProxyService service = new RssProxyService(null, null, null);

            Assert.Throws<ArgumentNullException>(() 
                => service.GetArticlesAsync(null));
        }

        [Test, SilverlightUnitTest]
        public void GetArticlesAsync_RssMapperPassed_GetMappedItemsCalled()
        {
            IRssMapper rssMapper = Isolate.Fake.Instance<IRssMapper>();
            WebClient webClient = Isolate.Fake.Instance<WebClient>();
            Func<WebClient> webClientFactory = () => webClient;
            RssProxyService service = new RssProxyService(webClientFactory, "http://simple.com", rssMapper);

            service.GetArticlesAsync(articles => { });
            var e = Isolate.Fake.Instance<DownloadStringCompletedEventArgs>();
            Isolate.WhenCalled(() => e.Result).DoInstead( context => "fake rss string");
            Isolate.Invoke.Event(() => webClient.DownloadStringCompleted += null, null, e);

            Isolate.Verify.WasCalledWithExactArguments(() => rssMapper.GetMappedItems("fake rss string"));
        }

        [Test, SilverlightUnitTest]
        public void GetArticlesAsync_UriPassed_WebClientInvokedDownloadStringAsyncWithUri()
        {
            WebClient webClient = Isolate.Fake.Instance<WebClient>();
            Func<WebClient> webClientFactory = () => webClient;
            RssProxyService service = new RssProxyService(webClientFactory, "http://simple.com", null);

            service.GetArticlesAsync(articles => { });

            Uri uri = new Uri("http://simple.com", UriKind.Absolute);
            Isolate.Verify.WasCalledWithExactArguments(()
                => webClient.DownloadStringAsync(uri));
        }

        [Test, SilverlightUnitTest]
        public void GetArticlesAsync_CallbackPassed_CallbackCalled()
        {
            IRssMapper rssMapper = Isolate.Fake.Instance<IRssMapper>();
            var webClient = Isolate.Fake.Instance<WebClient>();
            Func<WebClient> webClientFactory = () => webClient;
            var service = new RssProxyService(webClientFactory, "http://simple.com", rssMapper);

            bool isDelegateCalled = false;
            service.GetArticlesAsync(articles => isDelegateCalled = true);
            var e = Isolate.Fake.Instance<DownloadStringCompletedEventArgs>();
            Isolate.Invoke.Event(() => webClient.DownloadStringCompleted += null, null, e);
            Assert.True(isDelegateCalled);
        }
    }
}
